/**
 * @file usr_adc_handle.c
 * @author 黑马小乌龟 (532352406@qq.com)
 * @brief
 * @version 0.1
 * @date 2025-07-13
 *
 * @copyright Copyright (c) 2025
 *
 */
#include "usr_cfg.h"
#include "usr_adc_handle.h"

uint16_t m_au16AdcValue[DMA_BLOCK_SIZE];
uint16_t m_au16AdcValue_adc3[1];
uint16_t m_au16AdcValue_adc2[ADC2_DMA_BLOCK_SIZE]={1,2,3};

int adc_finished_flg=0;


/**
 * @brief  DMA interrupt configuration.
 * @param  None
 * @retval None
 */
static void DmaIrqConfig(void)
{

    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_FLAG_BTC_CH1);
    DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_FLAG_BTC_CH2);



    /* NVIC setting */
    NVIC_ClearPendingIRQ(DMA_INT_IRQn);
    NVIC_SetPriority(DMA_INT_IRQn, DMA_INT_PRIO);
    NVIC_EnableIRQ(DMA_INT_IRQn);
}
/**
 * @brief  DMA IRQ handler.
 * @param  None
 * @retval None
 */
// void DMA_IRQ_HANDLER(void) {
//     if (DMA_GetTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG) == SET) {
//         DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_INT_FLAG);
//         adc_finished_flg = 1;
//     }
//     if (DMA_GetTransCompleteStatus(DMA_UNIT, DMA_FLAG_BTC_CH1) == SET) {
//         DMA_ClearTransCompleteStatus(DMA_UNIT, DMA_FLAG_BTC_CH1);
//         // DDL_Printf("F1\n");
//     }

//     __DSB(); /* Arm Errata 838869 */
// }
/**
 * @brief  DMA configuration.
 * @param  None
 * @retval None
 */
static void DmaConfig(void)
{
    stc_dma_init_t stcDmaInit;
    stc_dma_repeat_init_t stcDmaRptInit;

    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    stcDmaInit.u32SrcAddr     = (uint32_t)&ADC_UNIT->DR6;
    stcDmaInit.u32DestAddr    = DMA_DEST_ADDR;
    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;
    stcDmaInit.u32BlockSize   = DMA_BLOCK_SIZE;
    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;

    /* Enable DMA peripheral clock and AOS function. */
    FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);
    (void)DMA_Init(DMA_UNIT, DMA_CH, &stcDmaInit);

    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;
    stcDmaRptInit.u32SrcCount  = DMA_BLOCK_SIZE;
    stcDmaRptInit.u32DestCount = DMA_BLOCK_SIZE;
    (void)DMA_RepeatInit(DMA_UNIT, DMA_CH, &stcDmaRptInit);

    /* Enable AOS clock */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* Set DMA trigger source */
    AOS_SetTriggerEventSrc(DMA_AOS_TRIG_SEL, DMA_TRIG_EVT);

    /* DMA IRQ configuration. */
    DmaIrqConfig();

    DMA_Cmd(DMA_UNIT, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_CH, ENABLE);
}


/**
 * @brief  Set specified ADC pin to analog mode.
 * @param  None
 * @retval None
 */
static void AdcSetPinAnalogMode(void) {
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(ADC_Vout_PORT, ADC_Vout_PIN, &stcGpioInit);
    (void)GPIO_Init(ADC_Vin_PORT, ADC_Vin_PIN, &stcGpioInit);
}

/**
 * @brief  Initializes ADC.
 * @param  None
 * @retval None
 */
void AdcConfig(void) {
    stc_adc_init_t stcAdcInit;
    // stc_irq_signin_config_t stcIrq;

    /* 1. Enable ADC peripheral clock. */
    FCG_Fcg3PeriphClockCmd(ADC_PERIPH_CLK, ENABLE);
    /* 2. Modify the default value depends on the application. Not needed here. */
    (void)ADC_StructInit(&stcAdcInit);
    /* 3. Initializes ADC. */
    (void)ADC_Init(ADC_UNIT, &stcAdcInit);
    /* 4. ADC channel configuration. */
    /* 4.1 Set the ADC pin to analog input mode. */
    AdcSetPinAnalogMode();
    /* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if
     * needed. */
    // ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_Vin_CH, ENABLE);
    ADC_ChCmd(ADC_UNIT, ADC_SEQ, ADC_Vout_CH, ENABLE);

#if ADC_EVENT_TRIGGER
    /* 5. Conversion data average calculation function, if needed.
          Call ADC_ConvDataAverageChCmd() again to enable more average channels if
       needed. */
    /* Specifies the event defined by 'ADC_SEQB_TRIG_EVT' as the hard trigger of sequence B. */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    ADC_TriggerConfig(ADC_UNIT, ADC_SEQ, ADC_SEQA_HARDTRIG);
    AOS_SetTriggerEventSrc(ADC_SEQA_AOS_TRIG_SEL, ADC_SEQA_TRIG_EVT);
    ADC_TriggerCmd(ADC_UNIT, ADC_SEQ, ENABLE);
#endif

    // ADC_ConvDataAverageConfig(ADC_UNIT, ADC_AVG_CNT64);
    // ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_Vin_CH, ENABLE);
    // ADC_ConvDataAverageChCmd(ADC_UNIT, ADC_Vout_CH, ENABLE);
    // /* 6. Ser over sample mode and right shift number */
    // ADC_SetSampleMode(ADC_UNIT, ADC_SAMPLE_MD_OVER);
    // ADC_SetOverSampleShift(ADC_UNIT, ADC_OVER_SAMPLE_SHIFT_2BIT);

    // stcIrq.enIntSrc    = ADC_SEQA_INT_SRC;
    // stcIrq.enIRQn      = ADC_SEQA_INT_IRQn;
    // stcIrq.pfnCallback = &ADC1_SeqA_IrqCallback;
    // (void)INTC_IrqSignIn(&stcIrq);
    // NVIC_ClearPendingIRQ(stcIrq.enIRQn);
    // NVIC_SetPriority(stcIrq.enIRQn, ADC_SEQA_INT_PRIO);
    // NVIC_EnableIRQ(stcIrq.enIRQn);

    // ADC_IntCmd(ADC_UNIT, ADC_INT_EOCA, ENABLE);
#if ADC_EVENT_TRIGGER
     DmaConfig();
#endif

}


/**
 * @brief  Set specified ADC pin to analog mode.
 * @param  None
 * @retval None
 */
static void Adc3SetPinAnalogMode(void) {
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(ADC_CurrO_PORT, ADC_CurrO_PIN, &stcGpioInit);
}

/**
 * @brief  DMA configuration.
 * @param  None
 * @retval None
 */
static void DmaConfig_for_adc3(void)
{
    stc_dma_init_t stcDmaInit;
    stc_dma_repeat_init_t stcDmaRptInit;

    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    stcDmaInit.u32SrcAddr     =  ((uint32_t)&CM_ADC3->DR8);
    stcDmaInit.u32DestAddr    = ((uint32_t)(&m_au16AdcValue_adc3[0U]));
    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;
    stcDmaInit.u32BlockSize   = sizeof(m_au16AdcValue_adc3)/sizeof(uint16_t);
    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;

    /* Enable DMA peripheral clock and AOS function. */
    FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);
    (void)DMA_Init(DMA_UNIT, DMA_CH1, &stcDmaInit);

    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;
    stcDmaRptInit.u32SrcCount  = sizeof(m_au16AdcValue_adc3)/sizeof(uint16_t);
    stcDmaRptInit.u32DestCount = sizeof(m_au16AdcValue_adc3)/sizeof(uint16_t);
    (void)DMA_RepeatInit(DMA_UNIT, DMA_CH1, &stcDmaRptInit);

    /* Enable AOS clock */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* Set DMA trigger source */
    AOS_SetTriggerEventSrc(AOS_DMA_1, EVT_SRC_ADC3_EOCA);

    /* DMA IRQ configuration. */
    // DmaIrqConfig_for_adc3();

    DMA_Cmd(DMA_UNIT, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_CH1, ENABLE);
}


/**
 * @brief  Initializes ADC.
 * @param  None
 * @retval None
 */
void Adc3_Config(void) {
    stc_adc_init_t stcAdcInit;
    // stc_irq_signin_config_t stcIrq;

    /* 1. Enable ADC peripheral clock. */
    FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_ADC3, ENABLE);
    /* 2. Modify the default value depends on the application. Not needed here. */
    (void)ADC_StructInit(&stcAdcInit);
    /* 3. Initializes ADC. */
    (void)ADC_Init(CM_ADC3, &stcAdcInit);
    /* 4. ADC channel configuration. */
    /* 4.1 Set the ADC pin to analog input mode. */
    Adc3SetPinAnalogMode();
    /* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if
     * needed. */
    ADC_ChCmd(CM_ADC3, ADC_SEQ_A, ADC_CurrO_CH, ENABLE);
    // ADC_ChCmd(CM_ADC3, ADC_SEQ_A, ADC_Vout_CH, ENABLE);

#if ADC_EVENT_TRIGGER
    /* 5. Conversion data average calculation function, if needed.
          Call ADC_ConvDataAverageChCmd() again to enable more average channels if
       needed. */
    /* Specifies the event defined by 'ADC_SEQB_TRIG_EVT' as the hard trigger of sequence B. */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    ADC_TriggerConfig(CM_ADC3, ADC_SEQ_A, ADC_HARDTRIG_EVT1);
    AOS_SetTriggerEventSrc(AOS_ADC3_1, ADC_SEQA_TRIG_EVT);
    ADC_TriggerCmd(CM_ADC3, ADC_SEQ_A, ENABLE);
#endif

    // ADC_ConvDataAverageConfig(CM_ADC3, ADC_AVG_CNT64);
    // ADC_ConvDataAverageChCmd(CM_ADC3, ADC_CH0, ENABLE);
    
    /* 6. Ser over sample mode and right shift number */
    // ADC_SetSampleMode(CM_ADC3, ADC_SAMPLE_MD_OVER);
    // ADC_SetOverSampleShift(CM_ADC3, ADC_OVER_SAMPLE_SHIFT_2BIT);

    // stcIrq.enIntSrc    = INT_SRC_ADC3_EOCA;
    // stcIrq.enIRQn      = INT015_IRQn;
    // stcIrq.pfnCallback = &test_ADC3_SeqA_IrqCallback;
    // (void)INTC_IrqSignIn(&stcIrq);
    // NVIC_ClearPendingIRQ(stcIrq.enIRQn);
    // NVIC_SetPriority(stcIrq.enIRQn, ADC_SEQA_INT_PRIO);
    // NVIC_EnableIRQ(stcIrq.enIRQn);

    // ADC_IntCmd(CM_ADC3, ADC_INT_EOCA, ENABLE);

    // ADC_Start(CM_ADC3);

#if ADC_EVENT_TRIGGER
     DmaConfig_for_adc3();
#endif

}




/**
 * @brief  Set specified ADC pin to analog mode.
 * @param  None
 * @retval None
 */
static void Adc2SetPinAnalogMode(void) {
    stc_gpio_init_t stcGpioInit;

    (void)GPIO_StructInit(&stcGpioInit);
    stcGpioInit.u16PinAttr = PIN_ATTR_ANALOG;
    (void)GPIO_Init(NTC_ADC_CH_PORT, NTC_ADC_CH_PIN, &stcGpioInit);
     (void)GPIO_Init(ADC_Vin_PORT, ADC_Vin_PIN, &stcGpioInit);
}

/**
 * @brief  DMA configuration.
 * @param  None
 * @retval None
 */
static void DmaConfig_for_adc2(void)
{
    stc_dma_init_t stcDmaInit;
    stc_dma_repeat_init_t stcDmaRptInit;

    (void)DMA_StructInit(&stcDmaInit);
    stcDmaInit.u32IntEn       = DMA_INT_ENABLE;
    stcDmaInit.u32SrcAddr     =  ((uint32_t)&CM_ADC2->DR7);
    stcDmaInit.u32DestAddr    = ((uint32_t)(&m_au16AdcValue_adc2[0U]));
    stcDmaInit.u32DataWidth   = DMA_DATA_WIDTH;
    stcDmaInit.u32BlockSize   = sizeof(m_au16AdcValue_adc2)/sizeof(uint16_t);
    stcDmaInit.u32TransCount  = DMA_TRANS_CNT;
    stcDmaInit.u32SrcAddrInc  = DMA_SRC_ADDR_INC;
    stcDmaInit.u32DestAddrInc = DMA_DEST_ADDR_INC;

    /* Enable DMA peripheral clock and AOS function. */
    FCG_Fcg0PeriphClockCmd(DMA_PERIPH_CLK, ENABLE);
    (void)DMA_Init(DMA_UNIT, DMA_CH2, &stcDmaInit);

    stcDmaRptInit.u32Mode      = DMA_RPT_BOTH;
    stcDmaRptInit.u32SrcCount  = sizeof(m_au16AdcValue_adc2)/sizeof(uint16_t);
    stcDmaRptInit.u32DestCount = sizeof(m_au16AdcValue_adc2)/sizeof(uint16_t);
    (void)DMA_RepeatInit(DMA_UNIT, DMA_CH2, &stcDmaRptInit);

    /* Enable AOS clock */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    /* Set DMA trigger source */
    AOS_SetTriggerEventSrc(AOS_DMA_2, EVT_SRC_ADC2_EOCA);

    /* DMA IRQ configuration. */
    // DmaIrqConfig_for_adc3();
        /* DMA IRQ configuration. */
    // DmaIrqConfigADC2();

    DMA_Cmd(DMA_UNIT, ENABLE);
    DMA_ChCmd(DMA_UNIT, DMA_CH2, ENABLE);
}


/**
 * @brief  Initializes ADC.
 * @param  None
 * @retval None
 */
void Adc2_Config(void) {
    stc_adc_init_t stcAdcInit;
    // stc_irq_signin_config_t stcIrq;

    /* 1. Enable ADC peripheral clock. */
    FCG_Fcg3PeriphClockCmd(FCG3_PERIPH_ADC2, ENABLE);
    /* 2. Modify the default value depends on the application. Not needed here. */
    (void)ADC_StructInit(&stcAdcInit);
    /* 3. Initializes ADC. */
    (void)ADC_Init(CM_ADC2, &stcAdcInit);
    /* 4. ADC channel configuration. */
    /* 4.1 Set the ADC pin to analog input mode. */
    Adc2SetPinAnalogMode();
    /* 4.2 Enable ADC channels. Call ADC_ChCmd() again to enable more channels if
     * needed. */
    ADC_ChCmd(CM_ADC2, ADC_SEQ_A, NTC_ADC_CH, ENABLE);
    ADC_ChCmd(CM_ADC2, ADC_SEQ_A, ADC_Vin_CH, ENABLE);

#if ADC_EVENT_TRIGGER
    /* 5. Conversion data average calculation function, if needed.
          Call ADC_ConvDataAverageChCmd() again to enable more average channels if
       needed. */
    /* Specifies the event defined by 'ADC_SEQB_TRIG_EVT' as the hard trigger of sequence B. */
    FCG_Fcg0PeriphClockCmd(FCG0_PERIPH_AOS, ENABLE);
    ADC_TriggerConfig(CM_ADC2, ADC_SEQ_A, ADC_HARDTRIG_EVT1);
    AOS_SetTriggerEventSrc(AOS_ADC2_1, ADC_SEQA_TRIG_EVT);
    ADC_TriggerCmd(CM_ADC2, ADC_SEQ_A, ENABLE);
#endif

    // ADC_ConvDataAverageConfig(CM_ADC2, ADC_AVG_CNT64);
    // ADC_ConvDataAverageChCmd(CM_ADC2, ADC_CH0, ENABLE);
    
    /* 6. Ser over sample mode and right shift number */
    // ADC_SetSampleMode(CM_ADC2, ADC_SAMPLE_MD_OVER);
    // ADC_SetOverSampleShift(CM_ADC2, ADC_OVER_SAMPLE_SHIFT_2BIT);

    // stcIrq.enIntSrc    = INT_SRC_ADC3_EOCA;
    // stcIrq.enIRQn      = INT015_IRQn;
    // stcIrq.pfnCallback = &test_ADC3_SeqA_IrqCallback;
    // (void)INTC_IrqSignIn(&stcIrq);
    // NVIC_ClearPendingIRQ(stcIrq.enIRQn);
    // NVIC_SetPriority(stcIrq.enIRQn, ADC_SEQA_INT_PRIO);
    // NVIC_EnableIRQ(stcIrq.enIRQn);

    // ADC_IntCmd(CM_ADC2, ADC_INT_EOCA, ENABLE);

    // ADC_Start(CM_ADC2);

#if ADC_EVENT_TRIGGER
     DmaConfig_for_adc2();
#endif

}




